package com.lbh.platforms.windows;

import com.lbh.platforms.windows.structures.gdi.RECT;
import com.lbh.structures.math.Quaternion;
import com.lbh.structures.math.Vector3;
import com.lbh.structures.components.render.Mesh;

import static com.lbh.platforms.windows.WinOpenGL32.*;

/***
 * project:JRuntime
 * package:com.lbh
 *
 * @author user:lenovo QQ:1601078366
 * @date 2021/10/19 1:21
 * @version V1.0
 */
@SuppressWarnings("AlibabaCommentsMustBeJavadocFormat")
public class WinRender {

    private static Vector3 camPos = new Vector3(0.0F, 0.0F, -5.0F);
    // 此时 x 向左， y 向上, z 向前
    private static WinGameObject cube = WinGameObject.createPrimitive(Mesh.MESH_PRIMITIVE_CUBE);

    private static float theta = 0.0F;

    static {
        WinEvent.keyDownEvents.add(key -> {
            if (key == 'W'){
                camPos.z += 0.5F;
            } else if (key == 'A'){
                camPos.x += 0.5F;
            } else if (key == 'S'){
                camPos.z -= 0.5F;
            } else if (key == 'D'){
                camPos.x -= 0.5F;
            }
        });
    }

    public static void init(){
        ins.glEnable(GL_DEPTH_TEST);
        ins.glEnable(GL_ALPHA_TEST);
        ins.glEnable(GL_BLEND);
        ins.glEnable(GL_CULL_FACE);
        ins.glEnable(GL_NORMALIZE);

        ins.glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE_MINUS_SRC_ALPHA);
        ins.glCullFace(GL_BACK);
    }

    private static void initCamera(){
        RECT rect = new RECT();
        WinUser32.ins.GetWindowRect(WinStart.hWnd, rect);

        ins.glMatrixMode(GL_PROJECTION);
        ins.glLoadIdentity();
        WinGlu32.ins.gluPerspective(60.0, ((double)rect.right - rect.left) / (rect.bottom - rect.top), 0.1, 100.0);

        ins.glMatrixMode(GL_MODELVIEW);
        ins.glLoadIdentity();
        WinGlu32.ins.gluLookAt(camPos.x, camPos.y, camPos.z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

        float[] mat = new float[16];

        ins.glMatrixMode(GL_PROJECTION);
        ins.glPushMatrix();
        ins.glGetFloatv(GL_PROJECTION_MATRIX, mat);
        ins.glLoadIdentity();

        ins.glMultMatrixf(mat);

        ins.glMatrixMode(GL_MODELVIEW);
        ins.glPushMatrix();
        ins.glGetFloatv(GL_MODELVIEW_MATRIX, mat);
        ins.glLoadIdentity();

        ins.glMultMatrixf(mat);
    }

    public static void render(){
        ins.glColorMask(true, true, true, true);
        ins.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        ins.glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
        ins.glClearDepth(1.0);

        initCamera();

        ins.glPushMatrix();
        ins.glRotatef(theta, 0.0F, 0.0F, 1.0F);
        ins.glBegin(GL_TRIANGLES);
        ins.glColor3f(1.0F, 0.0F, 0.0F); ins.glVertex3f(0.0F, 1.0F, 0.0F);
        ins.glColor3f(0.0F, 1.0F, 0.0F); ins.glVertex3f(0.87F, -0.5F, 0.0F);
        ins.glColor3f(0.0F, 0.0F, 1.0F); ins.glVertex3f(-0.87F, -0.5F, 0.0F);
        ins.glEnd();
        ins.glPopMatrix();

        ins.glPushMatrix();
        ins.glTranslatef(0.0F, -2.0F, 0.0F);
        ins.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        cube.render();
        cube.transform.rotation.mul(Quaternion.axisAngle(new Vector3(1.0F, 1.0F, 1.0F), 1.0F));
        ins.glPopMatrix();

        theta += 1.0F;

        cube.transform.rotation.normalize();
    }
}
